package com.ruoyi.bom.controller;

import com.ruoyi.bom.domain.FoodAndBom;
import com.ruoyi.bom.domain.TqlFood;
import com.ruoyi.bom.domain.TqlPandianPeriodVO;
import com.ruoyi.bom.dto.BillFoodPeriodDto;
import com.ruoyi.bom.dto.DeptProlossAndMarginDto;
import com.ruoyi.bom.dto.ProlossDto;
import com.ruoyi.bom.dto.TwoPeriodCompareDto;
import com.ruoyi.bom.service.ITqlDishBomService;
import com.ruoyi.bom.service.ITqlProlossService;
import com.ruoyi.bom.service.TqlFoodService;
import com.ruoyi.common.core.constant.CommonUtil;
import com.ruoyi.common.core.utils.CalculatedValueUtil;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.TimeUtils;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.redis.service.RedisService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/bomAnalsys")
public class TqlBomAnalsysController extends BaseController {

    @Autowired
    private TqlFoodService tqlFoodService;

    @Autowired
    private ITqlDishBomService iTqlDishBomService;


    @Autowired
    private ITqlProlossService iTqlProlossService;
    @Autowired
    private RedisService redisService;


    /**
     * 1.有那些food 没有bom
     *
     * @param pandianCode
     * @return
     * @throws ParseException
     */
    @GetMapping("/unUsedBom")
    public AjaxResult getunUsedBomInfo(String pandianCode) throws ParseException {
        FoodAndBom bom=new FoodAndBom();
        bom.setPandianCode(pandianCode);
        bom.setType(-1);
        List<FoodAndBom> array = tqlFoodService.queryBomAnalsys(bom);
        if (CollectionUtils.isEmpty(array)) {
            String fnumber = StringUtils.getPandianCodeInfo(pandianCode, 1);
            String yyyymm = StringUtils.getPandianCodeInfo(pandianCode, 2);
            int month=TimeUtils.getMonth(yyyymm, CommonUtil.yyyyMMdd);
//

            /**
             *    <select id="findEnableGenPharse" resultType="com.tql.pandian.vo.TqlPandianPeriodVO" parameterType="java.lang.String">
             *         select s.pcode, s.deptCode, m.starttime, m.endtime
             *         from tql_pandian_period_shop s
             *         left join tql_pandian_period m on s.pid= m.id
             *         where s.pandianCode=#{pandianCode}
             *     </select>
             */
            TqlPandianPeriodVO period = tqlFoodService.findEnableGenPharse(pandianCode);
            period.setDeptCode(fnumber);
            List<TqlFood> list = tqlFoodService.findUnUserFoodInfo(fnumber);

            if (CollectionUtils.isEmpty(list)) return success();
            List<FoodAndBom> list1 = new ArrayList<>();
            for (TqlFood each : list) {
                FoodAndBom food = new FoodAndBom();
                food.setId(UUID.randomUUID().toString());
                food.setFoodCode(each.getFoodCode());
                food.setFoodName(each.getFoodName());
                food.setUnit(each.getUnit());
                FoodAndBom food1 = tqlFoodService.findUnUserFoodCountAndSumAmount(food, period, month);
                food.setSumcount(null == food1||null== food1.getSumcount() ? 0 : food1.getSumcount());
                food.setSumAmount(null == food1||null==food1.getSumAmount() ? new BigDecimal(0) : food1.getSumAmount());
                food.setType(-1);
                food.setPandianCode(pandianCode);
                food.setShopID(fnumber);
                food.setMonth(yyyymm);
                food.setFnumber(fnumber);
                list1.add(food);
            }
            tqlFoodService.insertBomAnalsysByUnusedBom(list1);
            return success(list1);
        } else {
            return success(array);
        }

    }

    /**
     * 2.成本卡未使用原材料
     * bom里面没有的原材料 ，in有消耗
     select stapCode,stapName,unitName,price,inNum,inAmout
     from tql_stap_proloss
     where inNum >0
     and stapCode not in(select b.stap_code from tql_bom b
     left join tql_dish_bom d on b.dish_id=d.id
     left join sys_dept sd on d.dept_id=sd.dept_id
     where sd.dept_code like  concat(#{param1},'%') )
     and pandianCode =#{param2}
     */
    @GetMapping("/stapByunUsedBom")
    public AjaxResult StapByunUsedBom(String pandianCode) throws ParseException {

        String fnumber = StringUtils.getPandianCodeInfo(pandianCode, 1);

        //先查这个店bom里面所有原材料
        //iTqlDishBomService
       List<ProlossDto> list=iTqlDishBomService.findProloss(fnumber,pandianCode);
       return success(list);
    }




    /**
     * 3.无审定成本卡产品列表
     *
     * --没有锁定的产品
     */
    @GetMapping("/statFoodUnlocked")
    public AjaxResult statFoodUnlocked(String pandianCode) throws ParseException {


        String fnumber = StringUtils.getPandianCodeInfo(pandianCode, 1);
        TqlFood food=new TqlFood();
        food.setIsLock("1");
        food.setDepartmentId(fnumber);
        List<TqlFood> list=tqlFoodService.findAllFood(food);
        if(!CollectionUtils.isEmpty(list))
        {
            String[] foodCodes = list.stream()
                    .map(TqlFood::getFoodCode)
                    .toArray(String[]::new);

            List<BillFoodPeriodDto> list1=tqlFoodService.findBillFoodPeriod(pandianCode,foodCodes);
            return success(list1);
        }


        return success();






    }


    /**
     * 4.
     *
     *
     * TYPE 成本卡偏大1   成本卡偏小 2
     */


    @GetMapping("/bomCardParse")
    public AjaxResult bomCardParse(@RequestParam("pandianCode") String pandianCode, @RequestParam("type")String type) throws ParseException {

        String key="BCP"+pandianCode;
        String value=redisService.getCacheObject(key);
//        if(Objects.isNull(value))//说明没有进项BOM判断
//        {
//            insertBomcardAnalys(pandianCode,periodData,prolossData);
//        }



        if(null==type) return success();
        List<FoodAndBom> list=null;
        //TYPE 成本卡偏大1 对应数据库（type =1 或者 type >2） 且 type!=-1
        if("1".equals(type))
        {
          list= tqlFoodService.findBomCardParse(pandianCode,type);
        }
        else if("2".equals(type))
        {
             list= tqlFoodService.findBomCardParse(pandianCode,type);
        }
        return success(list);
    }



    @GetMapping("/deptProloss")
    public AjaxResult deptProloss(@RequestParam("pandianCode") String pandianCode,@RequestParam(value = "flag",defaultValue = "0") String flag) throws ParseException {

        List<DeptProlossAndMarginDto> list0=tqlFoodService.findDeptProlossAndMargin(pandianCode);
        if(!CollectionUtils.isEmpty(list0)&&"0".equals(flag))
            return success(list0);
        String fnumber = StringUtils.getPandianCodeInfo(pandianCode, 1);
        String shopCode=fnumber+"002";
        /**
         select tt.shopCode as deptCode,tt.deptName,sum(tt.sumAmount) as sumAmount,sum(tt.scost) as standardCost from(

         select a.foodCode,a.sumcount*a.cost as scost,a.sumAmount,t.shopCode ,t.dept_name as deptName
         from tql_bom_analsys a
         left join (
         select  b.shopCode,f.foodCode,d.dept_name
         from tql_dish_bom b
         left join sys_dept d on b.shopCode=d.dept_code
         left join  tql_food f on b.food_id=f.foodID
         where b.shopCode like   concat(#{shopCode},'%')
         and f.foodCode is not null) t
         on a.foodCode=t.foodCode
         where pandianCode=#{pandianCode}
         )tt
         GROUP BY tt.shopCode,tt.deptName

         */
        List<DeptProlossAndMarginDto> list=tqlFoodService.findDeptProloss(pandianCode,shopCode);
        //实际成本=期初+（采购-调出+调入）-期末
        //实际成本=lastcost+incost-thiscost
        //lastPandianSumCost+thisPandianSumIn-thisPandianSumCost
        String[] deptCodes=list.stream().map(DeptProlossAndMarginDto::getDeptCode).toArray(String[]::new);
       // String lastPandianCode=getLastPandianCode(pandianCode);
        //if(StringUtils.isEmpty(lastPandianCode))

            //RealCost
            /**
             * select deptCode,sum(inAmout) as realCost from tql_stap_proloss
             * where pandiancode='BU1010010024P20240229S4'
             * group by deptCode
             */
            //得到realCost

        if(null!=deptCodes&&deptCodes.length>0) {
            List<DeptProlossAndMarginDto> list1 = tqlFoodService.findRealCost(pandianCode, deptCodes);
            Map<String, DeptProlossAndMarginDto> map = list1.stream().collect(Collectors.toMap(DeptProlossAndMarginDto::getDeptCode, Function.identity()));
            list.stream().forEach(item -> {
                DeptProlossAndMarginDto dto = map.getOrDefault(item.getDeptCode(), new DeptProlossAndMarginDto());
                BigDecimal realCost=dto.getRealCost();
                BigDecimal stardCost=item.getStandardCost();
                BigDecimal sumAmount=item.getSumAmount();
                item.setRealCost(realCost);
                //损益=实际成本-标准成本
                BigDecimal proloss= CalculatedValueUtil.subtractionBigDecimal(realCost,null==stardCost?new BigDecimal(0):stardCost);
                item.setProloss(proloss);
                //损益率=损益/标准成本
                BigDecimal prolossRate= CalculatedValueUtil.division(
                        (null == proloss || proloss.compareTo(BigDecimal.ZERO) == 0) ? BigDecimal.ZERO:realCost
                        ,null==stardCost?new BigDecimal(0):stardCost);
                item.setProlossRate(prolossRate);
                //标准毛利率=标准成本/销售额
                BigDecimal standardProMargin=CalculatedValueUtil.division(
                        (null == stardCost || stardCost.compareTo(BigDecimal.ZERO) == 0) ? BigDecimal.ZERO:realCost,
                        null==sumAmount?new BigDecimal(0):sumAmount);
                item.setStandardProMargin(standardProMargin);
                //实际毛利率=实际成本/销售额
                BigDecimal realProMargin=CalculatedValueUtil.division(
                        (null == realCost || realCost.compareTo(BigDecimal.ZERO) == 0) ? BigDecimal.ZERO:realCost
                        ,null==sumAmount?new BigDecimal(0):sumAmount);
                item.setRealProMargin(realProMargin);
               item.setPandianCode(pandianCode);
            });

        }
        if(!CollectionUtils.isEmpty(list))
        {
            tqlFoodService.delDeptProlossAndMargin(pandianCode);
            tqlFoodService.insertDeptProlossAndMargin(list);
        }

        return success(list);
    }



    private String getLastPandianCode(String pandianCode) {
        String lastPandianCode =tqlFoodService.getLastPandianCode(pandianCode);
        return lastPandianCode;
    }


    /**
     *
     * @param pandianCode
     * @param flag 1两期都盘盈
     * @return
     * @throws ParseException
     */

    @GetMapping("/twoPeriodCompare")
    public AjaxResult twoPeriodCompare(@RequestParam("pandianCode") String pandianCode,@RequestParam(value = "flag",defaultValue = "1") String flag) throws ParseException {

        String lastPandianCode =getLastPandianCode(pandianCode);
        if(StringUtils.isEmpty(lastPandianCode))
            return AjaxResult.success("没有上期盘点编码，无法判断两期的情况");
        List<TwoPeriodCompareDto> list= iTqlProlossService.twoPeriodCompare(pandianCode,lastPandianCode,flag);
        return  AjaxResult.success(list);


    }

    @GetMapping("/twoPeriodCompareDetail")
    public AjaxResult twoPeriodCompareDetail(@RequestParam("ids") String ids) throws ParseException {
        List<TwoPeriodCompareDto> list= iTqlProlossService.twoPeriodCompareDetail(ids);
        return  AjaxResult.success(list);


    }








    }